package com.talent.core.protocol.mqtt.handler;

import com.talent.core.protocol.mqtt.TlMqttSession;
import com.talent.core.protocol.mqtt.config.Constant;
import com.talent.core.protocol.mqtt.model.entity.TlMessage;
import com.talent.core.protocol.mqtt.model.entity.TlSubClient;
import com.talent.core.protocol.mqtt.model.entity.TlTopic;
import com.talent.core.protocol.mqtt.model.request.TlMqttPublishReq;
import com.talent.core.protocol.mqtt.store.IMqttStore;
import com.talent.core.protocol.mqtt.task.RemoveSessionTask;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.AttributeKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName：TlMqttException
 * @Author: hszhou
 * @Date: 2024/11/25 14:37
 * @Description: 必须描述类做什么事情, 实现什么功能
 */
@ChannelHandler.Sharable
public class TlMqttExceptionHandler extends ChannelInboundHandlerAdapter {

    private static final  Logger logger = LoggerFactory.getLogger(TlMqttExceptionHandler.class);

    private IMqttStore mqttStore;

    public TlMqttExceptionHandler(IMqttStore mqttStore){
        this.mqttStore = mqttStore;
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {

       Boolean disconnectFlag= (Boolean)ctx.channel().attr(AttributeKey.valueOf(Constant.DISCONNECT)).get();
        //这里是非正常断开

        String clientId = ctx.channel().attr(AttributeKey.valueOf(Constant.CLIENT_ID)).get().toString();
        logger.info("客户端【{}】断开连接",clientId);

        //将客户端的会话通道置空
        TlMqttSession session = mqttStore.getSessionByClientId(clientId);
        session.setCtx(null);
        ctx.channel().eventLoop().schedule(()->{
            new RemoveSessionTask(clientId,session.getTopics(),mqttStore).remove();
        },5, TimeUnit.MINUTES);

        if(disconnectFlag){
            return;
        }

        logger.debug("客户端{}非正常断开连接",clientId);
        TlMessage willMessage = session.getWillMessage();
        if (willMessage != null) {
            String topic = willMessage.getTopic();
            //向订阅的主题发送遗嘱消息
            List<TlSubClient> subClients = mqttStore.getSubClientByTopic(topic);
            for (TlSubClient subClient : subClients) {
                logger.debug("获取到订阅遗嘱主题的{}的客户端为{}", topic, subClients.size());
                TlMqttSession subSession = subClient.getSession();
                ChannelHandlerContext channelHandlerContext = subSession.getCtx();
                TlMqttPublishReq req = willMessage.getReq();
                logger.debug("遗嘱消息是{}",req);
                channelHandlerContext.channel().writeAndFlush(req);
            }
        }

        ctx.channel().close();

    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        //获取该客户端的遗嘱消息
        logger.error("出现异常{}",cause.getCause());

       // ctx.channel().close();
    }
}
